package com.niodata.dp.web.module.hub;

import com.niodata.dp.core.usermgr.model.UserInfo;
import com.niodata.dp.task.entity.PluginCategoryCountSta;
import com.niodata.dp.task.entity.PluginDocumentView;
import com.niodata.dp.task.entity.PluginPackage;
import com.niodata.dp.task.entity.PluginPackageView;
import com.niodata.dp.task.service.PluginHubManager;
import com.niodata.dp.task.service.PluginManager2;
import com.niodata.dp.util.FileUtil;
import com.niodata.dp.util.IdUtil;
import com.niodata.dp.web.PageInfo;
import com.niodata.dp.web.module.base.BaseController;
import com.niodata.dp.web.module.task.PluginPackageController2;
import com.niodata.dp.web.security.ContextUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("hub/v1/plugin/")
public class PluginHubController extends BaseController {

  private static final Logger logger = Logger.getLogger(PluginPackageController2.class);

  @Autowired
  @Qualifier("PluginHubManagerImpl")
  private PluginHubManager hubManager;

  @Autowired
  @Qualifier("PluginManager2Impl")
  private PluginManager2 pluginManager;

  @RequestMapping(value = "view/category_sta", method = RequestMethod.GET)
  @ResponseBody
  public Object getPluginCategoryCount() {
    PluginCategoryCountSta categorysta =
          this.hubManager.getPluginCategoryCount();
    return categorysta;
  }


  /**
   * 分页查询插件列表信息.
   *
   * @param pageIndex 查询页码，默认第一页
   * @param pageSize 每页显示数，默认20
   * @return 查询的信息
   */
  @RequestMapping(value = {"/view/list"}, method = {RequestMethod.GET})
  public Object getPackageList(
        @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
        @RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize,
        @RequestParam(value = "sysCategory", required = false) String sysCategory,
        @RequestParam(value = "funcCategory", required = false) String funcCategory,
        @RequestParam(value = "nameContains", required = false) String nameContains) {
    nameContains = nameContains != null && nameContains.length() > 0 ? nameContains : null;
    List<PluginPackageView> pluginList =
          this.hubManager.getPlugins(
                sysCategory, funcCategory, nameContains,
                (pageIndex - 1) * pageSize,
                pageSize + 1
          );

    PageInfo pageInfo = new PageInfo();
    pageInfo.setHasMore(pluginList.size() > pageSize);
    pageInfo.setPageIndex(pageIndex);
    pageInfo.setStart((pageIndex - 1) * pageSize + 1);
    if (pluginList.size() > pageSize) {
      pluginList.remove(pluginList.size() - 1);
    }
    pageInfo.setStop((pageIndex - 1) * pageSize + pluginList.size());
    return this.getPagedResult(pluginList, pageInfo);
  }

  @RequestMapping(value = "/view/doc", method = RequestMethod.GET)
  @ResponseBody
  public Object getDocument(@RequestParam("pkgId") String pkgId) {
    PluginDocumentView view = this.hubManager.getPluginDocumentView(pkgId);
    return this.getResult(view);
  }

  /**
   * download plugin.
   *
   * @param name name
   * @param version version
   * @param response res
   * @throws IOException ioe
   */
  @RequestMapping(value = "/view/download")
  public void downLoadPlugin(@RequestParam("name") String name,
        @RequestParam("version") String version,
        HttpServletResponse response) throws IOException {
    if (!pluginManager.exists(name, version)) {
      response.setStatus(HttpServletResponse.SC_NOT_FOUND);
      response.getWriter().println("插件不存在");
      return;
    }
    String tmpDir = "tmp/" + IdUtil.uuid();
    File tmpDirFile = new File(tmpDir);
    try {
      tmpDirFile.mkdirs();
      this.pluginManager.copyPluginFilesToLocal(name, version, tmpDir);
      String localPath = tmpDir + "/" + name + "/" + version + "/" + name + "-" + version;
      File file = new File(localPath);
      if (!file.exists()) {
        throw new RuntimeException("file not exists:" + file.getAbsolutePath());
      }
      File out = new File(file.getName() + ".zip");
      response.setHeader("Content-Disposition", "attachment; filename="
            + new String(out.getName().getBytes(StandardCharsets.UTF_8),
            StandardCharsets.ISO_8859_1));
      response.setContentType("application/octet-stream");
      FileUtil.zipFolderContent(file, out);
      FileInputStream fileInputStream = new FileInputStream(out);
      IOUtils.copy(fileInputStream, response.getOutputStream());
      fileInputStream.close();
      response.getOutputStream().flush();
      hubManager.incrDownTimes(name, version, 1);
      out.delete();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      FileUtil.deleteFileOrDir(new File(tmpDir));
    }
  }

  /**
   * 查询插件详细信息.
   *
   * @param name plugin name
   * @param version plugin version
   * @return 对应的插件信息
   */
  @RequestMapping(value = {"/view/detail"}, method = RequestMethod.GET)
  public Object getPackageDetail(
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "version", required = false) String version,
        HttpServletResponse response) {
    PluginPackage pluginPackage = null;
    if (name != null && version != null) {
      UserInfo userInfo = ContextUtil.getCurrentUser();
      pluginPackage = this.pluginManager
            .getPluginByNameVersion(0, name, version);
    } else {
      response.setStatus(HttpStatus.SC_BAD_REQUEST);
      return getResult("param error");
    }
    return this.getResult(pluginPackage);
  }

}
